package com.example.byexample

fun main() {
    // 集合

    // List
    addSystemUser(4)
    println("Tot sudoers: ${getSysSudoers().size}")
    getSysSudoers().forEach { i ->
        println("Some useful info on user: $i")
    }

    // Set 无序不重复
    val aNewIssue: String = "uniqueDescr4"
    val anIssueAlreadyIn: String = "uniqueDescr2"
    println("Issue $aNewIssue ${getStatusLog(addIssue(aNewIssue))}")
    println("Issue $anIssueAlreadyIn ${getStatusLog(addIssue(anIssueAlreadyIn))}")

    // Map 键/值对的集合
    accountsReport()                                                                    // 6
    updatePointsCredit(1)                                                               // 7
    updatePointsCredit(1)
    updatePointsCredit(5)                                                               // 8
    accountsReport()

    // filter函数 过滤集合
    val numbers = listOf<Int>(1, -2, 3, -4, 5, -6)
    val positives = numbers.filter { i -> i > 0 }
    val negatives = numbers.filter { it < 0 }
    println("positives $positives")
    println("negatives $negatives")

    // map函数 转换元素
    val doubled = numbers.map { x -> x * 2 }
    val tripled = numbers.map { it * 3 }
    println("doubled $doubled")
    println("tripled $tripled")

    val anyNegative = numbers.any { it < 0 }
    println("anyNegative $anyNegative")
    val anyGT6 = numbers.any { it > 6 }
    println("anyGT6 $anyGT6")

    var allEven = numbers.all { it % 2 == 0 }
    println("allEven $allEven")
    var allLess6 = numbers.all { it < 6 }
    println("allLess6 $allLess6")

    allEven = numbers.none { it % 2 == 1 }           // 2
    println("allEven $allEven")
    allLess6 = numbers.none { it > 6 }               // 3
    println("allLess6 $allLess6")

    val words = listOf("Lets", "find", "something", "in", "collection", "somehow")  // 1
    val first = words.find { it.startsWith("some") }                                // 查找以“some”开头的第一个单词。
    val last = words.findLast { it.startsWith("some") }                             // 查找以“some”开头的最后一个单词。
    val nothing = words.find { it.contains("nothing") }                             // 查找包含“nothing”的第一个单词。
    println("first $first last $last nothing $nothing")

    data class Person(val name: String, val city: String, val phone: String) // 1

    val people = listOf(                                                     // 2
        Person("John", "Boston", "+1-888-123456"),
        Person("Sarah", "Munich", "+49-777-789123"),
        Person("Svyatoslav", "Saint-Petersburg", "+7-999-456789"),
        Person("Vasilisa", "Saint-Petersburg", "+7-999-123456")
    )

    val phoneBook = people.associateBy { it.phone }                          // 3
    println("phoneBook $phoneBook")
    val cityBook = people.associateBy(Person::phone, Person::city)           // 4
    println("cityBook $cityBook")
    val peopleCities = people.groupBy(Person::city, Person::name)            // 5
    println("peopleCities $peopleCities")
    val lastPersonCity = people.associateBy(Person::city, Person::name)      // 6
    println("lastPersonCity $lastPersonCity")

    val evenOdd = numbers.partition { it % 2 == 0 }           // 2
    println("evenOdd $evenOdd")
    val (positives, negatives) = numbers.partition { it > 0 } // 3
    println("positives $positives")
    println("negatives $negatives")

    val fruitsBag = listOf("apple", "orange", "banana", "grapes")  // 1
    val clothesBag = listOf("shirts", "pants", "jeans")           // 2
    val cart = listOf(fruitsBag, clothesBag)                    // 3
    val mapBag = cart.map { it }                                // 4
    val flatMapBag = cart.flatten()                        // 5
}

const val POINTS_X_PASS: Int = 15
val EZPassAccounts: MutableMap<Int, Int> = mutableMapOf(1 to 100, 2 to 100, 3 to 100)
val EZPassReport: Map<Int, Int> = EZPassAccounts

fun updatePointsCredit(accountId: Int) {
    if (EZPassAccounts.containsKey(accountId)) {                                        // 3
        println("Updating $accountId...")
        EZPassAccounts[accountId] = EZPassAccounts.getValue(accountId) + POINTS_X_PASS  // 4
    } else {
        println("Error: Trying to update a non-existing account (id: $accountId)")
    }
}

fun accountsReport() {
    println("EZ-Pass report:")
    EZPassReport.forEach {                                                              // 5
            (k, v) ->
        println("ID $k: credit $v")
    }
}

val openIssues: MutableSet<String> = mutableSetOf("uniqueDescr1", "uniqueDescr2", "uniqueDescr3")

fun addIssue(uniqueDesc: String): Boolean {
    return openIssues.add(uniqueDesc)
}

fun getStatusLog(isAdded: Boolean): String {
    return if (isAdded) "registered correctly." else "marked as duplicate and rejected."
}

val systemUsers: MutableList<Int> = mutableListOf(1, 2, 3)
val sudoers: List<Int> = systemUsers

fun addSystemUser(newUser: Int) {
    systemUsers.add(newUser)
}

fun getSysSudoers(): List<Int> {
    return sudoers
}
